//
//      Author: Alexandros Sigalas
//
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.


#ifndef MESH
#define MESH

#include "globals.h"
#include "polygon.h"
#include "mathutils.h"
#include "material.h"
#include "bounds.h"


#define ME_DEFAULT_SIZE_V 400
#define ME_DEFAULT_SIZE_F 300
#define ME_DEFAULT_SIZE_E 1000

enum EdgeFlags{ COPLANAR= 1, CREASE= 2, PROJECT=4};
typedef struct M_Vert{
	vec co;
	int flags;
}*mvert;

struct M_Face;

typedef struct FaceList{
    struct M_Face **faces;
    uint last;
    uint size;
}*facelist;

typedef struct M_Edge{
	int flags;
	mvert v0;
	mvert v1;
	facelist users;
}*medge;

typedef struct M_Face{
	mvert verts[3];
	medge edges[3];
	material mat;
    int flags;
}*mface; 

typedef struct Mesh{
	mface faces;
	medge edges;
	mvert verts;
	material mat;
	unsigned int size_v, size_e, size_f;
	unsigned int last_v, last_e, last_f;
	struct Bounds bb;
}*mesh;

mesh me_init(void);
void me_kill(mesh *me_pt);

mface me_add_face(mesh me, uint vx0, uint vx1, uint vx2);
int me_del_face(mesh me, uint idx);
int me_kill_face(mesh me, uint idx);

mvert me_add_vert(mesh me, vec * co);
int me_del_vert(mesh me, uint idx);

medge me_find_edge(mesh me, uint idx0, uint idx1);
medge me_add_edge(mesh me, uint idx, uint vx1);
int me_del_edge(mesh me, uint idx);
int me_kill_edge(mesh me, uint idx);

uint me_edge_faces(mesh me, medge edge, uint *users);
uint me_vertex_edges(mesh me, mvert vx, uint *users);
void me_mark_creases(mesh me, float angle);

void mf_normal(mface face, vec *no);
facelist mf_adjascent_faces(mface f);
polylist me_to_polys(mesh me, double thresh, uint *coplanar_id);

/// FACELIST
facelist fl_init(uint count);
void fl_append(facelist *fl_pt, mface face);
void fl_extend(facelist *fl_pt, mface *faces, unsigned int count);
mface fl_pop(facelist fl);
mface fl_remove(facelist fl, unsigned int idx);
int fl_remove_f(facelist fl, mface face);

void fl_kill(facelist *fl_pt);
void fl_killall(facelist *fl_pt);

#endif







